<?php
declare (strict_types=1);

namespace app\common\model;

use addons\Target\facade\Target;
use think\helper\Str;

class TradeOffline extends Base
{
    protected $type = [
        'finish_time' => 'timestamp',
        'cancel_time' => 'timestamp'
    ];

    protected function user(): object
    {
        return $this->hasOne(User::class, 'id', 'uid')
            ->field('id,code,nickname,mobile,photo');
    }

    protected function getAccountAttr($value): string
    {
        return get_pay_way($value);
    }

    protected function getTypeNameAttr($value, $data): string
    {
        return getTradeType($data['type_id']);
    }

    protected function getStatusNameAttr($value, $data): string
    {
        return getTradeStatus($data['status']);
    }

    public static function add($param, $user, $system): array
    {
        parent::startTrans();
        try {
            if (empty($system['trade_offline_open'])) {
                throw new \Exception('交易功能已关闭');
            }
            if ($system['trade_offline_publish_min'] > $param['amount']) {
                throw new \Exception('最低挂单数量：' . $system['trade_offline_publish_min']);
            }
            if (!empty($system['trade_offline_publish_bs'])) {
                if ($param['amount'] % $system['trade_offline_publish_bs'] != 0) {
                    throw new \Exception('挂单倍数：' . $system['trade_offline_publish_bs']);
                }
            }
            if (md5($param['pay_password']) != $user->pay_password) {
                throw new \Exception('支付密码错误');
            }
            $account = $param['account'];
            $method = explode(',', $param['method']);
            if ($param['type_id'] == 1) {
                if (in_array('bank', $method) && empty($user->bank_number)) {
                    throw new \Exception('请完善' . get_pay_way('bank') . '收款方式');
                }
                if (in_array('wechat', $method) && empty($user->wechat_image)) {
                    throw new \Exception('请完善' . get_pay_way('wechat') . '收款方式');
                }
                if (in_array('alipay', $method) && empty($user->alipay_image)) {
                    throw new \Exception('请完善' . get_pay_way('alipay') . '收款方式');
                }
                if (in_array('usdt', $method) && empty($user->usdt_address)) {
                    throw new \Exception('请完善' . get_pay_way('usdt') . '收款方式');
                }
                $param['cost_rate'] = $system['trade_offline_cost'];
                $real_amount = round($param['amount'] * (1 + $system['trade_offline_cost']), 2);
                if ($real_amount > $user->assets->$account) {
                    throw new \Exception(get_pay_way($account) . '账户余额不足');
                }
                Target::Account()->basics($user->id, $account, $real_amount, '挂卖', '-')
                    ->createNormal();
                $param['sn'] = 'S' . date('YmdHis') . Str::random(6, 1) . $user->id;
            } else {
                $param['sn'] = 'B' . date('YmdHis') . Str::random(6, 1) . $user->id;
            }
            $param['uid'] = $user->id;
            $param['surplus_amount'] = $param['amount'];
            parent::create($param);
            parent::commit();

            return ['code' => 1, 'msg' => '发布成功'];
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function revoke($param, $user): array
    {
        parent::startTrans();
        try {
            $info = parent::where(['id' => $param['id'], 'uid' => $user->id, 'status' => 1])->find();
            if (empty($info)) {
                throw new \Exception('交易不存在或是已完成');
            }
            $count = TradeOfflineOrder::where(['trade_id' => $param['id']])->whereIn('status', [1, 2, 5])->count();
            if ($count) {
                throw new \Exception('该交易有交易中的订单，无法撤消');
            }
            $info->status = 3;
            $info->cancel_time = time();
            $info->save();
            if ($info->type_id == 1 && $info->surplus_amount > 0) {
                $real_amount = round($info->surplus_amount * (1 + $info->cost_rate), 2);
                Target::Account()->basics($user->id, $info->getData('account'), $real_amount, '挂卖撤消', '+')
                    ->createNormal();
            }
            parent::commit();

            return ['code' => 1, 'msg' => '撤消成功'];
        } catch (\Exception $e) {
            parent::rollback();

            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }
}